#-*- coding: utf-8 -*-

#This file is part of pyLot library.
#
# pyLot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyLot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pyLot.  If not, see <http://www.gnu.org/licenses/>.

__author__ = u'Pierre Puiseux, Guillaume Baty'
__copyright__ = u"Copyright 2011-2012 (C) andheo, Université de Pau et des Pays de l'Adour"
__credits__ = [u'Pierre Puiseux', u'Guillaume Baty']
__license__ = "GNU Lesser General Public License"

__all__ = ['Handler']

from traits.api import implements

from .impl_basehandler import BaseHandler
from ..interfaces.i_handler import IHandler

from _pylot.defaultconf import hardbook
from _pylot.minimal.container import Container
from _pylot.minimal.datum_xml import xml_to_container, container_to_xml
from _pylot.minimal.path import Path
from _pylot.minimal.system import error, ENCODING
from _pylot.minimal.utils import find_file

class Handler(BaseHandler):
  implements(IHandler)

  identifier = 'pyLot.handler.anonymous'
  alias = property(fget=lambda self:self.identifier)
  desc = u''

  abilities = []

  def __init__(self):
    BaseHandler.__init__(self)
    self._user_options = []
    self._options = {}

  def addOptions(self, filepath, main=False, user=True):
    u"""
    Reads a csv :class:`~pylot.core.Configuration` file (filename) and adds 
    it to handler's options.

    :param filename: csv Collection file.
    :param user: if True, it saves configuration in userconf directory. See (read|write)Settings
    :type user: :obj:`bool`
    :param main: if main is True, option can be reached directly via "opt" attribute.
    
    :return: corresponding Configuration
    :rtype: :class:`~pylot.core.Configuration`w
    """
    obj = xml_to_container(filepath)

    if obj.name is None :
      raise NameError, error(tr_(u'%s must be named') % obj.__name__)
    else :
      setattr(self, u'_opt_%s' % obj.name, obj)
      if main is True :
        setattr(self, u'opt', obj)
      self._options[obj.name] = obj
      if obj not in self._user_options and user is True:
        self._user_options.append(obj)

    return obj

  def writeSettings(self, userconf_dir, recursive=True):
    for module in self :
      module.writeSettings(userconf_dir, recursive)
    settings = Container(name=u'settings', alias=self.identifier.decode(ENCODING))
    for opt in self._user_options :
      settings.add(opt)
    path = Path(userconf_dir, u'%s.xml' % self.identifier)
    container_to_xml(settings, path, mode=u'light')

  def readSettings(self, userconf_dir, recursive=True):
    for module in self :
      module.readSettings(userconf_dir, recursive)
    path = Path(userconf_dir, u'%s.xml' % self.identifier)
    if path.isfile():
      settings = xml_to_container(path, mode=u'light')
      for opt in self._user_options :
        try :
          block = settings[opt.name]
        except KeyError :
          pass
        else :
          opt.userUpgrade(block)

  def findFile(self, filename):
    u"""
    Searches file "filename" in plugin directory and default directories.
    filename can be a simple filename (ex: u'sample.conf') or a relative
    path (ex: Path(u'subdir', u'sample.conf'))
    
    :type filename: obj:`unicode` or :class:`~_pylot.minimal.path.Path`
    :return: absolute path or None
    :rtype: obj:`None` or :class:`~_pylot.minimal.path.Path`
    """
    return find_file(filename, hardbook(u'defaultconf'))
